package com.niodata.dp.web.module.app;

import com.niodata.dp.app.AppInfo;
import com.niodata.dp.app.AppManager;
import com.niodata.dp.core.OwnerType;
import com.niodata.dp.core.usermgr.model.GroupInfo;
import com.niodata.dp.core.usermgr.model.UserInfo;
import com.niodata.dp.core.usermgr.op.GroupInfoService;
import com.niodata.dp.util.IdUtil;
import com.niodata.dp.web.PageInfo;
import com.niodata.dp.web.module.base.BaseController;
import com.niodata.dp.web.security.ContextUtil;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/v1/app")
public class AppController extends BaseController {

  @Autowired
  @Qualifier("appManagerImpl")
  private AppManager appManager;

  @Autowired
  @Qualifier("DpUserMgrGroup")
  private GroupInfoService groupInfoService;

  /**
   * list user viewable apps.
   *
   * @param keyWord keyword
   * @param pageIndex page index
   * @param pageSize pagesize
   * @return list
   */
  @ResponseBody
  @RequestMapping("list")
  public Object listUserViewableApps(@RequestParam(name = "keyWord", required = false)
        String keyWord, @RequestParam(name = "pageIndex", required = true, defaultValue = "1")
        int pageIndex,
        @RequestParam(name = "pageSize", required = true, defaultValue = "20")
        int pageSize) {
    UserInfo userInfo = ContextUtil.getCurrentUser();

    List<AppInfo> appList =
          appManager.getUserAuthorizedApps(userInfo.getUserId(),
                keyWord, (pageIndex - 1) * pageSize, pageSize + 1);
    PageInfo pageInfo = new PageInfo();
    pageInfo.setPageIndex(pageIndex);
    pageInfo.setStart((pageIndex - 1) * pageSize + 1);
    int listSize = appList.size();
    if (listSize > pageSize) {
      pageInfo.setStop(pageInfo.getStart() + pageSize);
    } else {
      pageInfo.setStop(pageInfo.getStart() + listSize);
    }
    pageInfo.setHasMore(listSize > pageSize);
    return getPagedResult(
          listSize > pageSize ? appList.subList(0, listSize - 1) : appList, pageInfo);
  }

  @ResponseBody
  @RequestMapping("listall")
  public Object listUserApps(@RequestParam(name = "keyWord", required = false)
        String keyWord) {
    UserInfo userInfo = ContextUtil.getCurrentUser();

    List<AppInfo> appList =
          appManager.getUserApps(userInfo.getUserId(), keyWord);

    return getResult(appList);
  }

  @ResponseBody
  @RequestMapping("names")
  public Object listUserViewableAppName() {
    UserInfo userInfo = ContextUtil.getCurrentUser();
    List<AppInfo> appList =
          appManager.getUserAuthorizedApps(userInfo.getUserId(),
                null, 0, 100);
    List<AppNamePair> list = AppNamePair.build(appList);
    return getResult(list);
  }

  @ResponseBody
  @RequestMapping(method = RequestMethod.POST)
  public Object createApp(@RequestBody AppInfo appInfo) {
    UserInfo user = ContextUtil.getCurrentUser();
    appInfo.setAppId(IdUtil.uuid());
    if (appInfo.getOwnerType().equals(OwnerType.USER.name())) {
      appInfo.setOwnerId(user.getUserId());
      appInfo.setOwnerName(user.getUserName());
    } else {
      GroupInfo groupInfo = groupInfoService.getGroupInfo(appInfo.getOwnerId());
      appInfo.setOwnerName(groupInfo.getGroupName());
    }
    appInfo.setCrateTime(new Date());
    this.appManager.createApp(appInfo);
    return getResult(true);
  }

  @ResponseBody
  @RequestMapping(method = {RequestMethod.PUT})
  public Object updateApp(@RequestBody AppInfo appInfo) {
    AppInfo app = this.appManager.getByAppId(appInfo.getAppId());
    app.setDescription(appInfo.getDescription());
    app.setName(appInfo.getName());
    appManager.updateApp(app);
    return getResult(true);
  }

  @ResponseBody
  @RequestMapping(value = "del", method = RequestMethod.DELETE)
  public Object delete(@RequestParam("appId") String appId)
        throws IOException {
    appManager.deleteApp(appId);
    return getResult(true);
  }
}
